#ifndef AST_NODE
#define AST_NODE
#include <string>
#include "type.h"

namespace AST {

    /**
     * Nó como Estrutura Básica
     *
     * Estrutura básica para construção de uma árvore abstrata de sintaxe. Esta
     * estrutura pode ser especializada para receber outros conjuntos de nós
     * para formar uma árvore, conforme a necessidade.
     *
     * @category AST
     * @package  AST
     */
    class Node {

    private:

        /**
         * Tipagem de Informação
         */
        Type* _type;

        /**
         * Código do Token
         */
        int _token;

    public:

        /**
         * Configuração de Tipo
         *
         * Utilizado para configuração do tipo que é consultado durante a
         * análise semântica. Quando este valor não é configurado, consideramos
         * o tipo de dado armazenado como desconhecido.
         *
         * @param  Type* Elemento para Configuração
         * @return Próprio Objeto para Encadeamento
         */
        Node* setType(Type*);

        /**
         * Apresentação de Tipo
         *
         * Durante a análise semântica, este elemento é consultado para
         * verificação do tipo de informação que está armazenado. Quando este
         * tipo não estiver configurado, será apresentado um tipo desconhecido,
         * diferente de tipo vazio.
         *
         * @return Elemento Solicitado
         */
        Type* getType();

        /**
         * Configuração do Valor de Token
         *
         * @param  int   Código do Token Utilizado
         * @return Node* Próprio Objeto para Encadeamento
         */
        Node* setToken(int);

        /**
         * Apresentação do Valor do Token
         *
         * @return int Código do Token Utilizado
         */
        int getToken();

        /**
         * Construção de Espaços para Indentação
         *
         * Centralização da construção de espaços para indentação. Sempre que
         * houver a necessidade de construção destes elementos, devemos utilizar
         * este método para apresentar a quantidade correta de espaços. Isto é
         * necessário pois conforme necessidade, precisamos modificar a maneira
         * com que a indentação é executada.
         *
         * @param  int         Quantidade de Espaços para Processamento
         * @return std::string Conteúdo para Aplicação sobre Indentação
         */
        std::string getIndentSpaces(int);

        /**
         * Conversão para Exibição
         *
         * Representação do conjunto interno para utilização durante sua
         * visualização no sistema. Utilizado recursivamente para exibição e
         * usufruindo de polimorfismo.
         *
         * @param  int         Número da Indentação Atual
         * @return std::string Saída como Representação do Conteúdo Indentada
         */
        virtual std::string toString(int) = 0;

        /**
         * Checagem de Tipos
         *
         * Durante a análise semântica, precisamos executar as verificação de
         * forma interna. Estas sobrescritas devem verificar e configurar os
         * tipos resultantes dos elementos utilizados. Caso algum erro seja
         * encontrado, será executado o tratamento de erro da biblioteca.
         *
         * @return Próprio Objeto para Encadeamento
         */
        virtual Node* check();

    };

};

#endif

